-- List of vehicle models that are compatible with the jetHUD
local compatibleModels = {
    592,
    566,
    511,
    548,
    512,
    593,
    425,
    520,
    417,
    487,
    553,
    488,
    497,
    563,
    476,
    447,
    519,
    460,
    469,
    513
}

local sw, sh = guiGetScreenSize()
local iw, ih = 514, 514
local lineW = 2
local jetRender = dxCreateRenderTarget ( iw, ih, true )
local jetRender2 = dxCreateRenderTarget ( iw, ih, true )
local color = tocolor(255, 0, 0)

-- Returns true if the local player is piloting a vehicle compatible with the jetHUD, false otherwise
-- TODO: Check that the player is in the pilot's seat (no MTA function available?)
function isPilotingCompatibleVehicle()
	local vehicle = getPedOccupiedVehicle(localPlayer)
	if not vehicle then
		return false
	end
	
	local vehicleModel = getElementModel(vehicle)
	for _, compatibleModel in ipairs(compatibleModels) do
		if vehicleModel == compatibleModel then
			return true
		end
	end
	
	return false
end

-- Changes the camera position on pre-render (to avoid stuttering)
local function clientPreRender()
	if not isPilotingCompatibleVehicle() then
		return
	end
	
	local vehicle = getPedOccupiedVehicle(localPlayer)
	local cameraX, cameraY, cameraZ = getPositionFromElementOffset(vehicle, 0, -7, 4)
	local lookAtX, lookAtY, lookAtZ = getPositionFromElementOffset(vehicle, 0, 0, 2)
	local _, rotY= getElementRotation(vehicle)
	setCameraMatrix(cameraX, cameraY, cameraZ, lookAtX, lookAtY, lookAtZ, (rotY*-1))
end
addEventHandler("onClientPreRender", root, clientPreRender)

-- Renders the HUD
local function clientRender()
    if not isPilotingCompatibleVehicle() or not jetRender then
		return
	end
	
    local vehicle = getPedOccupiedVehicle(localPlayer)
    dxSetRenderTarget ( jetRender, true )
    local x, y, z = getElementPosition ( vehicle )
    local rx, ry, rz = getElementRotation ( vehicle )
    local sx, sy, sz = getElementVelocity ( vehicle )
    local speed = ( sx^2 + sy^2 + sz^2 ) ^ ( 0.5 )
    local mps = speed * 50
    local kmh = speed * 180
    local mph = speed * 111.847
    
	--speed
    dxDrawLine ( 1, 200, 1, 220, color, lineW )
    dxDrawLine ( 51, 200, 51, 220, color, lineW )
    dxDrawLine ( 1, 200, 51, 200, color, lineW )
    dxDrawLine ( 1, 220, 51, 220, color, lineW )
    dxDrawText ( math.round(kmh, 2), 1, 201, 49, 219, color, 1, "clear", "center", "center", true, false, false, false, false )
    
	--altitude
    dxDrawLine ( 463, 200, 463, 220, color, lineW )
    dxDrawLine ( 513, 200, 513, 220, color, lineW )
    dxDrawLine ( 463, 220, 513, 220, color, lineW )
    dxDrawLine ( 463, 200, 513, 200, color, lineW )
    dxDrawText ( math.round(z, 2), 464, 201, 512, 219, color, 1, "clear", "center", "center", true, false, false, false, false )
        
	--pitch rx
    --yaw rz
    --200 pixels, 40 degrees, every 5 pixels = 1 degree
    local pixelOffset = 5
    local rotmod = ( rz % 1 ) * pixelOffset
    local rotcal = math.floor( 200 - rotmod ) / pixelOffset
    for i=0,rotcal do
        if (i % 2 == 0) then
            dxDrawLine ( ( ( ( iw / 2 ) - 100 ) + rotmod + i * pixelOffset ), 40, ( ( ( iw / 2 ) - 100 ) + rotmod + i * pixelOffset ), 35, color, lineW )
        else
            dxDrawLine ( ( ( ( iw / 2 ) - 100 ) + rotmod + i * pixelOffset ), 40, ( ( ( iw / 2 ) - 100 ) + rotmod + i * pixelOffset ), 30, color, lineW )
        end
    end
    dxDrawText ( math.round(rz, 2), (iw/2)-25, 51, (iw/2)+25, 71, color, 1, "clear", "center", "center", true, false, false, false, false )
    dxDrawLine ( (iw/2)-10, 50, (iw/2), 40, color, lineW )
    dxDrawLine ( (iw/2)+10, 50, (iw/2), 40, color, lineW )
    --level crosshairs
    dxDrawLine ( (iw/2)-30, 220, (iw/2)+30, 220, color, lineW )
    dxDrawLine ( (iw/2), 220, (iw/2), 200, color, lineW )
    dxSetRenderTarget()
    --roll ry ( for rotating pitch )
    --400 pixels, 40 degrees, 10 pixels = 1 degree
    dxSetRenderTarget(jetRender2, true)
    local pixelOffset = 10
    local height = 300
    local rotmod = ( rx % 1 ) * pixelOffset
    local rotcal = math.floor( height - rotmod ) / pixelOffset
    for i=0,rotcal do
        if (i % 2 == 0) then
            dxDrawLine ( 65, ( ( ( iw / 2 ) - ( height / 2 ) ) + rotmod + i * pixelOffset ), 75, ( ( ( iw / 2 ) - ( height / 2 ) ) + rotmod + i * pixelOffset ), color, lineW )
            dxDrawLine ( (iw-65), ( ( ( iw / 2 ) - ( height / 2 ) ) + rotmod + i * pixelOffset ), (iw-75), ( ( ( iw / 2 ) - ( height / 2 ) ) + rotmod + i * pixelOffset ), color, lineW )
        else
            dxDrawLine ( 65, ( ( ( iw / 2 ) - ( height / 2 ) ) + rotmod + i * pixelOffset ), 70, ( ( ( iw / 2 ) - ( height / 2 ) ) + rotmod + i * pixelOffset ), color, lineW )
            dxDrawLine ( (iw-65), ( ( ( iw / 2 ) - ( height / 2 ) ) + rotmod + i * pixelOffset ), (iw-70), ( ( ( iw / 2 ) - ( height / 2 ) ) + rotmod + i * pixelOffset ), color, lineW )
        end
    end
    dxSetRenderTarget()
    dxDrawImage ( (sw/2)-(iw/2), (sh/2)-(ih/2), iw, ih, jetRender )
    dxDrawImage ( (sw/2)-(iw/2), (sh/2)-(ih/2), iw, ih, jetRender2,(ry*-1) )
end
addEventHandler("onClientRender", root, clientRender)

function math.round(number, decimals, method)
    decimals = decimals or 0
    local factor = 10 ^ decimals
    if (method == "ceil" or method == "floor") then return math[method](number * factor) / factor
    else return tonumber(("%."..decimals.."f"):format(number)) end
end

function getPositionFromElementOffset(element,offX,offY,offZ)
	local m = getElementMatrix ( element )  -- Get the matrix
	local x = offX * m[1][1] + offY * m[2][1] + offZ * m[3][1] + m[4][1]  -- Apply transform
	local y = offX * m[1][2] + offY * m[2][2] + offZ * m[3][2] + m[4][2]
	local z = offX * m[1][3] + offY * m[2][3] + offZ * m[3][3] + m[4][3]
	return x, y, z                               -- Return the transformed point
end

addEventHandler("onClientPlayerVehicleExit", localPlayer, function() setCameraTarget(localPlayer) end)
addEventHandler("onClientResourceStop", localPlayer, function() setCameraTarget(localPlayer) end)